package ar.com.gals.model;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

import ar.com.gals.domain.Articulo;
import ar.com.gals.domain.Equivalencia;
import ar.com.gals.domain.Observacion;
import ar.com.gals.domain.TipoEquivalencia;
import ar.com.gals.domain.TipoObservacion;
import ar.com.gals.error.GalsException;
import ar.com.gals.service.ArchivoService;
import ar.com.gals.service.ArticuloService;
import ar.com.gals.service.TipoEquivalenciaService;
import ar.com.gals.service.TipoObservacionService;

public class ArticuloModel {

	private String codigo;
	
	private String descripcion;
	
	private String rubro;
	
	private String marca;
	
	private String precio;
	
	private Integer archivo;
	
	private String archivoURL;
	
	private List<ObservacionModel> observaciones = new ArrayList<ObservacionModel>();
	
	private List<EquivalenciaModel> equivalencias = new ArrayList<EquivalenciaModel>();
	
	
	public ArticuloModel() {}

	public ArticuloModel(int articuloId) throws GalsException {
		Articulo articulo = new ArticuloService().getById(articuloId);
		this.setCodigo(articulo.getCodigo());
		this.setDescripcion(articulo.getDescripcion());
		this.setRubro(articulo.getRubro().getNombre());
		this.setMarca(articulo.getMarca().getNombre());
		this.setPrecio("$ " + new DecimalFormat("#0.00").format(articulo.getPrecio()));
		
		if(articulo.getArchivo() == null) {
			this.setArchivo(null);
			this.setArchivoURL("/GALS/BigImage/no_disponible.jpg");
		} else {
			this.setArchivo(articulo.getArchivo().getId());
			this.setArchivoURL("/GALS/BigImage/" + articulo.getArchivo().getNombre());
		}
		
		for(Observacion observacion : articulo.getObservaciones())
			this.addObservacion(new ObservacionModel(observacion));
		
		for(Equivalencia equivalencia : articulo.getEquivalencias())
			this.addEquivalencia(new EquivalenciaModel(equivalencia));
	}

	
	public String getCodigo() {
		return codigo;
	}
	public void setCodigo(String codigo) {
		this.codigo = codigo;
	}
	public String getDescripcion() {
		return descripcion;
	}
	public void setDescripcion(String descripcion) {
		this.descripcion = descripcion;
	}
	public String getRubro() {
		return rubro;
	}
	public void setRubro(String rubro) {
		this.rubro = rubro;
	}
	public String getMarca() {
		return marca;
	}
	public void setMarca(String marca) {
		this.marca = marca;
	}
	public String getPrecio() {
		return precio;
	}
	public void setPrecio(String precio) {
		this.precio = precio;
	}
	public Integer getArchivo() {
		return archivo;
	}
	public void setArchivo(Integer archivo) {
		this.archivo = archivo;
	}
	public String getArchivoURL() {
		return archivoURL;
	}
	public void setArchivoURL(String archivoURL) {
		this.archivoURL = archivoURL;
	}
	public List<ObservacionModel> getObservaciones() {
		return observaciones;
	}
	public void setObservaciones(List<ObservacionModel> observaciones) {
		this.observaciones = observaciones;
	}
	public void addObservacion(ObservacionModel observacion) {
		this.observaciones.add(observacion);
	}	
	public List<EquivalenciaModel> getEquivalencias() {
		return equivalencias;
	}
	public void setEquivalencias(List<EquivalenciaModel> equivalencias) {
		this.equivalencias = equivalencias;
	}
	public void addEquivalencia(EquivalenciaModel equivalencia) {
		this.equivalencias.add(equivalencia);
	}

	
	public List<TipoObservacion> getTiposDeObservacion() throws GalsException {
		return new TipoObservacionService().getAll();
	}
	
	public List<TipoEquivalencia> getTiposDeEquivalencia() throws GalsException {
		return new TipoEquivalenciaService().getAll();
	}

	
	public boolean hasError() {

		boolean hasError = false;
		
		for(ObservacionModel model : this.observaciones)
			if(model.bindError())
				hasError = true;
		
		for(EquivalenciaModel model : this.equivalencias)
			if(model.bindError())
				hasError = true;
		
		return hasError;
	}

	
	public void modificarArticulo(int articuloId) throws GalsException {
		
		ArticuloService service = new ArticuloService();
		
		Articulo articulo = service.getById(articuloId);
		
		// Imagen
		if(this.archivo == null) {
			articulo.setArchivo(null);
		}
		else if(articulo.getArchivo() == null || articulo.getArchivo().getId() != this.archivo) {
			ArchivoService service2 = new ArchivoService();
			articulo.setArchivo(service2.getById(this.archivo));			
		}
		
		// OBSERVACIONES
		List<Observacion> observacionesNuevas = new ArrayList<Observacion>();
		List<Observacion> observacionesDeBaja = new ArrayList<Observacion>();
		for(ObservacionModel observacionModel : this.observaciones) {
			switch (observacionModel.getMovimiento()) {
				case "A":
					if(observacionModel.getTipoObservacion() != null) {
						Observacion observacion = new Observacion();
						observacion.setArticulo(articulo);
						observacion.setTipoObservacion(new TipoObservacionService().getById(observacionModel.getTipoObservacion()));
						observacion.setValor(observacionModel.getValor());
						observacionesNuevas.add(observacion);
					}
					break;
					
				case "M":
					for(Observacion observacion : articulo.getObservaciones())
						if(observacionModel.getId() == observacion.getId()) {
							if(observacionModel.getTipoObservacion() != null) {
								if(observacionModel.getTipoObservacion() != observacion.getTipoObservacion().getId())
									observacion.setTipoObservacion(new TipoObservacionService().getById(observacionModel.getTipoObservacion()));
								observacion.setValor(observacionModel.getValor());
							}
							else {
								observacionesDeBaja.add(observacion);
							}
							break;
						}
					break;
					
				case "B":
					for(Observacion observacion : articulo.getObservaciones())
						if(observacionModel.getId() == observacion.getId()) {
							observacionesDeBaja.add(observacion);
						}
					break;
					
				default:
					throw new GalsException("No es posible procesar el tipo de movimiento");
			}
		}
		for(Observacion observacion : observacionesNuevas)
			articulo.getObservaciones().add(observacion);
		for(Observacion observacion : observacionesDeBaja)
			articulo.getObservaciones().remove(observacion);

		
		// EQUIVALENCIAS
		List<Equivalencia> equivalenciasNuevas = new ArrayList<Equivalencia>();
		List<Equivalencia> equivalenciasDeBaja = new ArrayList<Equivalencia>();
		for(EquivalenciaModel equivalenciaModel : this.equivalencias) {
			switch (equivalenciaModel.getMovimiento()) {
				case "A":
					if(equivalenciaModel.getTipoEquivalencia() != null) {
						Equivalencia equivalencia = new Equivalencia();
						equivalencia.setArticulo(articulo);
						equivalencia.setTipoEquivalencia(new TipoEquivalenciaService().getById(equivalenciaModel.getTipoEquivalencia()));
						equivalencia.setValor(equivalenciaModel.getValor());
						equivalenciasNuevas.add(equivalencia);
					}
					break;
					
				case "M":
					for(Equivalencia equivalencia : articulo.getEquivalencias())
						if(equivalenciaModel.getId() == equivalencia.getId()) {
							if(equivalenciaModel.getTipoEquivalencia() != null) {
								if(equivalenciaModel.getTipoEquivalencia() != equivalencia.getTipoEquivalencia().getId())
									equivalencia.setTipoEquivalencia(new TipoEquivalenciaService().getById(equivalenciaModel.getTipoEquivalencia()));
								equivalencia.setValor(equivalenciaModel.getValor());
							}
							else {
								equivalenciasDeBaja.add(equivalencia);
							}
							break;
						}
					break;
					
				case "B":
					for(Equivalencia equivalencia : articulo.getEquivalencias())
						if(equivalenciaModel.getId() == equivalencia.getId()) {
							equivalenciasDeBaja.add(equivalencia);
						}
					break;
					
				default:
					throw new GalsException("No es posible procesar el tipo de movimiento");
			}
		}
		for(Equivalencia equivalencia : equivalenciasNuevas)
			articulo.getEquivalencias().add(equivalencia);
		for(Equivalencia equivalencia : equivalenciasDeBaja)
			articulo.getEquivalencias().remove(equivalencia);
		
		// ACTUALIZACION DEL ARTICULO
		service.update(articulo);
	}
}
